PM_FUNC_NORM_ATTRIB SKILL:SkillBarrage( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Barrage", .Type = TYPE_NORMAL, .callTypes = CALL_SPAWN|CALL_WITH_SKILL_TIME, .PP = 20, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Get 2 to 5 grenades on spawn." );
		case CALL_SPAWN:
		{
			new Int:iOldGrenades = cs_get_user_bpammo( id, CSW_HEGRENADE );
			give_item( id, "weapon_hegrenade" );

			new Int:iGrenades = random_num( 2, 5 );
			cs_set_user_bpammo( id, CSW_HEGRENADE, iOldGrenades + iGrenades );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillBide( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Bide", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE|CALL_TAKE_DAMAGE, .PP = 10, .Charges = 2, .DelayTime = 10.0 );
		case CALL_HELP:     return SkillHelp( "Extra damage after being hurt." );
		case CALL_GIVE_DAMAGE:
		{
			new Int:iBideDamage = gSkillVariable[ id ];
			if ( iBideDamage )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = iBideDamage
							);
				return SKILL_USED;
			}
		}
		case CALL_TAKE_DAMAGE:
		{
			new Int:iBideDamage = floatround( StatClamp( id, STAT_SPECIAL, g_fDamage * 0.1, g_fDamage * 0.2 ) );
			gSkillVariable[ id ] += iBideDamage;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillBind( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Bind", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 20, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to paralyze someone when you attack them." );
		case CALL_GIVE_DAMAGE:
		{
			if ( StatChance( id, STAT_ATTACK, 25, 50 ) )
			{
				new Int:iParalysisTime = StatClamp( id, STAT_SPECIAL, 1, 10 );
				StatusApply( g_iVictim, id, STATUS_PARALYZE, iParalysisTime );

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillBite( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Bite", .Type = TYPE_NORMAL, .callTypes = CALL_PLAYER_TOUCH, .PP = 25, .Charges = 10, .DelayTime = 2.0 );
		case CALL_HELP:     return SkillHelp( "Damage players you touch." );
		case CALL_PLAYER_TOUCH:
		{
			SkillDamage( .victim = g_iVictim,
						.attacker = id,
						.damage = StatClamp( id, STAT_ATTACK, 1, 5 )
						);

			SoundHit( id );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillBodySlam( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Body Slam", .Type = TYPE_NORMAL, .callTypes = CALL_PLAYER_TOUCH, .PP = 15, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Paralyze players you touch." );
		case CALL_PLAYER_TOUCH:
		{
			new Int:iParalysisTime = StatClamp( id, STAT_SPECIAL, 1, 10 );
			StatusApply( g_iVictim, id, STATUS_PARALYZE, iParalysisTime );

			SoundHit( id );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillCometPunch( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Comet Punch", .Type = TYPE_NORMAL, .callTypes = CALL_SPEED_UPDATE|CALL_PLAYER_TOUCH, .PP = 15, .Charges = 1, .DelayTime = 0.1 );
		case CALL_HELP:     return SkillHelp( "Increased Speed & Damage players you touch." );
		case CALL_SPEED_UPDATE:
		{
			new Float:fSpeedIncrease = StatClamp( id, STAT_SPEED, 50.0, 75.0 );
			g_fSpeed += fSpeedIncrease;
			return SKILL_READY;
		}
		case CALL_PLAYER_TOUCH:
		{
			SkillDamage( .victim = g_iVictim,
						.attacker = id,
						.damage = StatClamp( id, STAT_ATTACK, 1, 10 )
						);

			SoundHit( id );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillConstrict( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Constrict", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 25, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to slow players you attack." );
		case CALL_GIVE_DAMAGE:
		{
			if ( StatChance( id, STAT_ATTACK, 25, 50 ) )
			{
				new Int:iSlowTime = StatClamp( id, STAT_SPECIAL, 5, 20 );
				StatusApply( g_iVictim, id, STATUS_SLOW, iSlowTime );

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillConversion( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Conversion", .Type = TYPE_NORMAL, .callTypes = CALL_EVERY_SECOND|CALL_WITH_SKILL_TIME|CALL_RESET, .PP = 30, .Charges = 300, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Blend in with the environment." );
		case CALL_EVERY_SECOND:
		{
			new Int:iAlphaVisibility = StatClamp( id, STAT_SPECIAL, 200, 50 );
			set_user_rendering( id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, iAlphaVisibility );
			return SKILL_USED;
		}
		case CALL_RESET:
		{
			new Int:iAlphaVisibility = 255;
			set_user_rendering( id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, iAlphaVisibility );
			return SKILL_READY;
		}

	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillCut( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Cut", .Type = TYPE_NORMAL, .callTypes = CALL_AIM_AT_PLAYER, .PP = 30, .Charges = 1, .DelayTime = 0.5 );
		case CALL_HELP:     return SkillHelp( "Damage players that are close when you look at them." );
		case CALL_AIM_AT_PLAYER:
		{
			if ( entity_range( id, g_iVictim ) <= StatClamp( id, STAT_SPECIAL, 100.0, 500.0 ) )
			{
				new Int:iDamage = StatClamp( id, STAT_ATTACK, 5, 25 );

				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = iDamage
							);

				EffectBeamEnts( .iPlayer = 0,
								.iStartEnt = id,
								.iEndEnt = g_iVictim,
								.iSprite = SPRITE_ROPE,
								.iStartFrame = 0,
								.iFrameRate = 10,
								.fLife = 1.0,
								.iLineWidth = iDamage,
								.iNoiseAmp = 10,
								.iRed = 0,
								.iGreen = 255,
								.iBlue = 0,
								.iAlpha = 255,
								.iScrollSpeed = 10
							);

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillDefenseCurl( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Defense Curl", .Type = TYPE_NORMAL, .callTypes = CALL_SPAWN|CALL_WITH_SKILL_TIME, .PP = 40, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Increased Armor on Spawn." );
		case CALL_SPAWN:
		{
			new CsArmorType:iArmorType;
			new Int:iOldArmor = cs_get_user_armor( id, iArmorType );
			if ( iArmorType == CS_ARMOR_NONE )
				iArmorType = CS_ARMOR_KEVLAR;

			new Int:iArmor = StatClamp( id, STAT_DEFENSE, 1, 300 );
			if ( iOldArmor < iArmor )
				cs_set_user_armor( id, iArmor, iArmorType );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillDisable( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Disable", .Type = TYPE_NORMAL, .callTypes = CALL_AIM_AT_PLAYER, .PP = 20, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Disable players skills when you look at them." );
		case CALL_AIM_AT_PLAYER:
		{
			new Float:fDelayTime = StatClamp( id, STAT_SPECIAL, 0.1, 10.0 );

			SkillAddDelay( g_iVictim, fDelayTime );

			SoundCast( id );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillDizzyPunch( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Dizzy Punch", .Type = TYPE_NORMAL, .callTypes = CALL_PLAYER_TOUCH, .PP = 10, .Charges = 10, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to make players flinch when you touch them." );
		case CALL_PLAYER_TOUCH:
		{
			if ( StatChance( id, STAT_ATTACK, 5, 25 ) )
			{
				StatusFlinch( g_iVictim );

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillDoubleTeam( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Double Team", .Type = TYPE_NORMAL, .callTypes = CALL_TAKE_DAMAGE, .PP = 15, .Charges = 10, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to evade shots from the enemy." );
		case CALL_TAKE_DAMAGE:
		{
			if ( is_weapon_gun( g_iWeaponID ) && StatChance( id, STAT_SPECIAL, 5, 25 ) )
			{
				g_fDamage = 0.0;

				new Int:iEnt = EntitySkillCreate( .iPlayer = id,
												.fKillTime = 5.0,
												.iProperty = SEP_KILL,
												.bPlayerOrigin = true,
												.bPlayerAngles = true
												);

				new String:szModel[64];
				pev( id, pev_model, szModel, charsmax(szModel) );
				entity_set_model( iEnt, szModel )

				new Float:fValue;
				pev( id, pev_gravity, fValue );
				set_pev( iEnt, pev_gravity, fValue );
				pev( id, pev_friction, fValue );
				set_pev( iEnt, pev_friction, fValue );
				pev( id, pev_frame, fValue );
				set_pev( iEnt, pev_frame, fValue );
				pev( id, pev_animtime, fValue );
				set_pev( iEnt, pev_animtime, fValue );
				pev( id, pev_framerate, fValue );
				set_pev( iEnt, pev_framerate, fValue );

				set_pev( iEnt, pev_controller_0, pev( id, pev_controller_0 ) );
				set_pev( iEnt, pev_controller_1, pev( id, pev_controller_1 ) );
				set_pev( iEnt, pev_controller_2, pev( id, pev_controller_2 ) );
				set_pev( iEnt, pev_controller_3, pev( id, pev_controller_3 ) );
				set_pev( iEnt, pev_blending_0, pev( id, pev_blending_0 ) );
				set_pev( iEnt, pev_blending_1, pev( id, pev_blending_1 ) );

				set_pev( iEnt, pev_skin, pev( id, pev_skin ) );
				set_pev( iEnt, pev_body, pev( id, pev_body ) );
				set_pev( iEnt, pev_sequence, pev( id, pev_sequence ) );
				set_pev( iEnt, pev_gaitsequence, pev( id, pev_gaitsequence ) );
				set_pev( iEnt, pev_rendermode, pev( id, pev_rendermode ) );
				set_pev( iEnt, pev_renderfx, pev( id, pev_renderfx ) );

				new Vector:vViewAngle[3];
				pev( id, pev_v_angle, vViewAngle );
				set_pev( iEnt, pev_v_angle, vViewAngle );

				SoundCast( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillDoubleEdge( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Double Edge", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 15, .Charges = 10, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance of getting an extra bullet when you attack players." );
		case CALL_GIVE_DAMAGE:
		{
			if ( is_weapon_gun( g_iWeaponID ) && StatChance( id, STAT_SPECIAL, 5, 25 ) )
			{
				new Int:iWeapEntity = PlayerWeaponEnt( id, g_iWeaponID );
				new Int:iOldAmmo = cs_get_weapon_ammo( iWeapEntity );
				cs_set_weapon_ammo( iWeapEntity, iOldAmmo + 1 );

				SoundHit( id );

				return SKILL_USED;
			}
			return SKILL_READY;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillDoubleslap( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Doubleslap", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 10, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to deal double knife damage." );
		case CALL_GIVE_DAMAGE:
		{
			if ( g_iWeaponID == CSW_KNIFE && StatChance( id, STAT_ATTACK, 25, 50 ) )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = floatround( g_fDamage )
							);

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillEggBomb( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Egg Bomb", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 10, .Charges = 3, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to deal extra grenade damage." );
		case CALL_GIVE_DAMAGE:
		{
			if ( g_iWeaponID == CSW_HEGRENADE && StatChance( id, STAT_ATTACK, 33, 100 ) )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = StatClamp( id, STAT_ATTACK, 10, 30 )
							);

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillExplosion( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Explosion", .Type = TYPE_NORMAL, .callTypes = CALL_DEATH, .PP = 5, .Charges = 10, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Damages nearby enemies when you die." );
		case CALL_DEATH:
		{
			new Coord:cOrigin[3];
			get_user_origin( id, cOrigin );

			new Float:fRadius = StatClamp( id, STAT_ATTACK, 300.0, 600.0 );
			new Int:iMaxDamage = StatClamp( id, STAT_ATTACK, 100, 500 );

			SkillAoEDamage( .attacker = id,
							.cOrigin = cOrigin,
							.fRadius = fRadius,
							.iMaxDamage = iMaxDamage,
							.flags = AOE_IGNORE_ATTACKER|AOE_VICTIM_TEAM
						);

			EffectBlastCircle( .cOrigin = cOrigin,
								.iSprite = SPRITE_SHOCKWAVE,
								.iRadius = floatround( fRadius ),
								.fLife = 1.0,
								.iWidth = iMaxDamage / 10,
								.iNoise = 0,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.iAlpha = 255
							);

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillFlash( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Flash", .Type = TYPE_NORMAL, .callTypes = CALL_TAKE_DAMAGE, .PP = 20, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to blind enemies that attack you." );
		case CALL_TAKE_DAMAGE:
		{
			if ( is_user_alive( g_iAttacker ) && StatChance( id, STAT_DEFENSE, 10, 33 ) )
			{
				new Int:iBrightness = StatClamp( id, STAT_SPECIAL, 150, 255 );
				new Float:fTime = StatClamp( id, STAT_SPECIAL, 0.5, 2.0 );

				EffectScreenFlash( .iPlayer = g_iAttacker,
									.iRed = 255,
									.iGreen = 255,
									.iBlue = 255,
									.iAlpha = iBrightness,
									.fTime = fTime,
									.iFadeFlags = ( 1 << 12 )
								);

				new Coord:cOrigin[3];
				get_user_origin( g_iAttacker, cOrigin );
				EffectDLight( .cOrigin = cOrigin,
								.iRadius = iBrightness / 10,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.fLife = fTime,
								.fDecay = 1.0
							);

				SoundCast( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillFocusEnergy( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Focus Energy", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN|CALL_GIVE_DAMAGE, .PP = 30, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Increases chances of critical hits." );
		case CALL_BIND_DOWN:
		{
			if ( !SkillCheck( id, CHECK_IN_AIR|CHECK_MOVING, .szAction = "Focus" ) )
			{
				new Int:iMaxEnergy = StatClamp( id, STAT_SPECIAL, 25, 250 );

				gSkillVariable[id] = min( gSkillVariable[id] + 1, iMaxEnergy );

				if ( gSkillVariable[id] == iMaxEnergy )
					client_print( id, print_center, "Focused Energy: %d%% (MAX)", gSkillVariable[id] );
				else
					client_print( id, print_center, "Focused Energy: %d%%", gSkillVariable[id] );

				new Coord:cOrigin[3];
				get_user_origin( id, cOrigin );
				EffectImplosion( .cOrigin = cOrigin,
								.iRadius = 50,
								.iCount = 5,
								.fLife = 0.5
							);

				return SKILL_READY;
			}
		}
		case CALL_GIVE_DAMAGE:
		{
			if ( gSkillVariable[id] && gSkillVariable[id] >= random(101) )
			{
				new Int:iEneryRelease = min( gSkillVariable[id], 100 );
				gSkillVariable[id] -= iEneryRelease;

				new Int:iDamage = floatround( g_fDamage * ( iEneryRelease / 100.0 ) );

				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = iDamage
							);

				client_print( id, print_center, "Energy Released!" );

				EffectBeamEnts( .iPlayer = 0,
								.iStartEnt = id,
								.iEndEnt = g_iVictim,
								.iSprite = SPRITE_SHOCKWAVE,
								.iStartFrame = 0,
								.iFrameRate = 10,
								.fLife = 1.0,
								.iLineWidth = iEneryRelease / 10,
								.iNoiseAmp = 20,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.iAlpha = 155,
								.iScrollSpeed = 10
							);

				SoundCast( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillFuryAttack( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Fury Attack", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 20, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to deal extra damage." );
		case CALL_GIVE_DAMAGE:
		{
			if ( StatChance( id, STAT_ATTACK, 15, 30 ) )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = floatround( StatClamp( id, STAT_SPECIAL, g_fDamage / 5.0, g_fDamage / 2.0 ) )
							);

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillFurySwipes( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Fury Swipes", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 15, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to deal extra knife damage." );
		case CALL_GIVE_DAMAGE:
		{
			if ( g_iWeaponID == CSW_KNIFE && StatChance( id, STAT_ATTACK, 25, 50 ) )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = floatround( StatClamp( id, STAT_SPECIAL, g_fDamage / 5.0, g_fDamage / 2.0 ) )
							);

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillGlare( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Glare", .Type = TYPE_NORMAL, .callTypes = CALL_AIM_AT_PLAYER, .PP = 30, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Paralyze enemies when you look at them." );
		case CALL_AIM_AT_PLAYER:
		{
			new Int:iParalysisTime = StatClamp( id, STAT_SPECIAL, 1, 3 );
			StatusApply( g_iVictim, id, STATUS_PARALYZE, iParalysisTime );

			SoundHit( id );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillGrowl( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Growl", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 40, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Removes bullets from the closest enemy's clip." );
		case CALL_BIND_DOWN:
		{
			new CsTeams:iTeam = cs_get_user_team( id );
			new Int:iTempWeapon;
			new Int:iEnemyWeapEntity;
			new Int:iOldClipAmmo;

			new Coord:cOrigin[3], Coord:cEnemyOrigin[3];
			get_user_origin( id, cOrigin );

			new Int:iClosestDist = StatClamp( id, STAT_SPECIAL, 500, 1000 );
			new Int:iClosestEnemy, Int:iTempDist;

			LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
			{
				if ( iTeam == cs_get_user_team( iPlayer ) )
					continue;

				iTempWeapon = get_user_weapon( iPlayer );
				if ( !is_weapon_gun( iTempWeapon ) )
					continue;

				iEnemyWeapEntity = PlayerWeaponEnt( iPlayer, iTempWeapon );
				iOldClipAmmo = cs_get_weapon_ammo( iEnemyWeapEntity );
				if ( !iOldClipAmmo )
					continue;

				get_user_origin( iPlayer, cEnemyOrigin );
				iTempDist = get_distance( cOrigin, cEnemyOrigin );
				if ( iTempDist < iClosestDist || !iClosestEnemy )
				{
					iClosestEnemy = iPlayer;
					iClosestDist = iTempDist;
				}
			}

			if ( iClosestEnemy )
			{
				iTempWeapon = get_user_weapon( iClosestEnemy );
				iEnemyWeapEntity = PlayerWeaponEnt( iClosestEnemy, iTempWeapon );
				iOldClipAmmo = cs_get_weapon_ammo( iEnemyWeapEntity );

				new Int:iAmmoTake = max( 1, StatClamp( id, STAT_SPECIAL, iOldClipAmmo / 4, 3 * iOldClipAmmo / 4 ) );
				if ( iAmmoTake )
				{
					SoundSpeak( iClosestEnemy, SOUND_AG_DIE );
					SoundEmit( id, SOUND_AG_DIE );

					cs_set_weapon_ammo( iEnemyWeapEntity, iOldClipAmmo - iAmmoTake );
					new Int:iOldBackAmmo = cs_get_user_bpammo(iClosestEnemy, iTempWeapon);
					cs_set_user_bpammo( iClosestEnemy, iTempWeapon, iOldBackAmmo + iAmmoTake );

					return SKILL_USED;
				}
			}
			else
			{
				client_print( id, print_center, "No player with gun close enough" );
				return SKILL_DENY;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillGrowth( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Growth", .Type = TYPE_NORMAL, .callTypes = CALL_EVERY_SECOND|CALL_WITH_SKILL_TIME, .PP = 40, .Charges = 300, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Reduces wait time for skills." );
		case CALL_EVERY_SECOND:
		{
			if ( g_fSkillReadyTime[id] )
			{
				g_fSkillReadyTime[id] -= StatClamp( id, STAT_SPECIAL, 0.5, 2.0 );
				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillGuillotine( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Guillotine", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 5, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Low chance for one hit kills with knife." );
		case CALL_GIVE_DAMAGE:
		{
			if ( g_iWeaponID == CSW_KNIFE && StatChance( id, STAT_ATTACK, 1, 5 ) )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = DAMAGE_AUTO_KILL
							);

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillGust( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Gust", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 35, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to push enemies back when you attack them." );
		case CALL_GIVE_DAMAGE:
		{
			if ( StatChance( id, STAT_ATTACK, 10, 45 ) )
			{
				new Int:iGustStrength = StatClamp( id, STAT_SPECIAL, 250, 450 );
				new Vector:vVelocity[3];

				velocity_by_aim( id, iGustStrength, vVelocity );
				vVelocity[2] = floatmax( vVelocity[2], 200.0 );

				EntitySetVelocity( g_iVictim, vVelocity );

				new Coord:cOrigin[3];
				get_user_origin( g_iVictim, cOrigin );
				cOrigin[2] -= 32;

				new Int:iRadius = 50;

				for ( new Int:i; i < 3; i++ )
				{
					EffectBlastCircle( .cOrigin = cOrigin,
										.iSprite = SPRITE_SHOCKWAVE,
										.iRadius = iRadius,
										.fLife = 1.0,
										.iWidth = 10,
										.iNoise = 0,
										.iRed = 255,
										.iGreen = 255,
										.iBlue = 255,
										.iAlpha = 255
									);

					cOrigin[2] += 32;
					iRadius += 10;
				}

				SoundCast( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillHarden( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Harden", .Type = TYPE_NORMAL, .callTypes = CALL_TAKE_DAMAGE, .PP = 30, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Increases armor when attacked." );
		case CALL_TAKE_DAMAGE:
		{
			new CsArmorType:iArmorType;
			new Int:iOldArmor = cs_get_user_armor( id, iArmorType );
			if ( iArmorType == CS_ARMOR_NONE )
				iArmorType = CS_ARMOR_KEVLAR;

			new Int:iArmorBonus = StatClamp( id, STAT_DEFENSE, 10, 20 );
			if ( iArmorBonus > 0 )
			{
				cs_set_user_armor( id, iOldArmor + iArmorBonus, iArmorType );

				SoundHit( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillHeadButt( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Head Butt", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 15, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillHornAttack( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Horn Attack", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 25, .Charges = 3, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Fires a horn that damages on contact." );
		case CALL_BIND_DOWN:
		{
			SoundHit( id );

			EntitySkillCreate( .iPlayer = id,
								.iProperty = SEP_TOUCH|SEP_DAMAGE|SEP_KILL,
								.iDamage = StatClamp( id, STAT_ATTACK, 30, 70 ),
								.iMoveType = MOVETYPE_FLY,
								.iSolidType = SOLID_TRIGGER,
								.iModel = MODEL_ROCKET,
								.iSound = SOUND_HIT,
								.iSprite = SPRITE_EEXPLO,
								.bPlayerOrigin = true,
								.bPlayerAngles = true,
								.vMins = Float:{-5.0,-5.0,-5.0},
								.vMaxs = Float:{5.0,5.0,5.0},
								.iAimVelocity = StatClamp( id, STAT_SPEED, 300, 700 )
							);

			return SKILL_USED_PAUSE;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillHornDrill( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Horn Drill", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 5, .Charges = 10, .DelayTime = 10.0 );
		case CALL_HELP:     return SkillHelp( "Rapidly fires horns that damages." );
		case CALL_BIND_DOWN:
		{
			SoundHit( id );

			EntitySkillCreate( .iPlayer = id,
								.iProperty = SEP_TOUCH|SEP_DAMAGE|SEP_KILL,
								.iDamage = StatClamp( id, STAT_ATTACK, 30, 70 ),
								.iMoveType = MOVETYPE_FLY,
								.iSolidType = SOLID_TRIGGER,
								.iModel = MODEL_ROCKET,
								.iSound = SOUND_HIT,
								.iSprite = SPRITE_EEXPLO,
								.bPlayerOrigin = true,
								.bPlayerAngles = true,
								.vMins = Float:{-5.0,-5.0,-5.0},
								.vMaxs = Float:{5.0,5.0,5.0},
								.iAimVelocity = StatClamp( id, STAT_SPEED, 300, 700 )
							);

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillHyperBeam( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Hyper Beam", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 5, .Charges = 10, .DelayTime = 10.0 );
		case CALL_HELP:     return SkillHelp( "Charge energy and then release as a powerful beam" );
		case CALL_BIND_DOWN:
		{
			#define HYPERBEAM_CHARGE  gSkillVector[ id ][0]
			#define HYPERBEAM_READY   gSkillVector[ id ][1]
			#define HYPERBEAM_DAMAGE  gSkillVector[ id ][2]
			if ( HYPERBEAM_READY <= 0.0 )
			{
				HYPERBEAM_CHARGE += 5.0;
				client_print( id, print_center, "Hyper Beam Charging: %d%%", floatround( HYPERBEAM_CHARGE ) );

				new Coord:cOrigin[3];
				get_user_origin( id, cOrigin );
				EffectImplosion( .cOrigin = cOrigin,
								.iRadius = 50,
								.iCount = 5,
								.fLife = 0.5
							);

				if ( HYPERBEAM_CHARGE >= 100.0 )
				{
					HYPERBEAM_READY = HYPERBEAM_CHARGE;

					SoundCast( id );
				}

				return SKILL_USED;
			}
			else
			{
				new Coord:cOrigin[3], Coord:cAim[3];
				get_user_origin( id, cOrigin );
				PlayerAimOrigin( id, cAim );

				new Float:fRadius = StatClamp( id, STAT_SPECIAL, 50.0, 250.0 );
				new Int:iMaxDamage = StatClamp( id, STAT_SPECIAL, 5, 15 );

				new Int:iLineDamage = SkillLineDamage( .attacker = id,
													.cStart = cOrigin,
													.cEnd = cAim,
													.fRadius = fRadius,
													.iMaxDamage = iMaxDamage,
													.flags = AOE_IGNORE_ATTACKER | AOE_VICTIM_TEAM
												);
				HYPERBEAM_DAMAGE += float( iLineDamage );

				EffectBeamEntPoint( .iPlayer = 0,
								.iStartEnt = id,
								.cEnd = cAim,
								.iSprite = SPRITE_ZBEAM6,
								.iStartFrame = 0,
								.iFrameRate = 10,
								.fLife = 0.1,
								.iLineWidth = floatround( fRadius ),
								.iNoiseAmp = 0,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.iAlpha = 255,
								.iScrollSpeed = 10
							);

				SoundEmit( id, SOUND_AG_DIE );

				HYPERBEAM_READY -= 10.0;
				if ( HYPERBEAM_READY <= 0.0 )
				{
					if ( PlayerGetInfo( id, PINFO_SETTING_SHOWDAMAGE ) )
						DHudEventMessage( id, "Hyper Beam did %d damage.", floatround( HYPERBEAM_DAMAGE ) );
					HYPERBEAM_CHARGE = HYPERBEAM_DAMAGE = 0.0;
				}

				return SKILL_USED;
			}
			#undef HYPERBEAM_CHARGE
			#undef HYPERBEAM_READY
			#undef HYPERBEAM_DAMAGE
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillHyperFang( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Hyper Fang", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 15, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillKarateChop( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Karate Chop", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 25, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Good chance of a critical hit." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillLeer( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Leer", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 30, .Charges = 3, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Chance to remove all armor from enemies you attack." );
		case CALL_GIVE_DAMAGE:
		{
			if ( StatChance( id, STAT_SPECIAL, 50, 100 ) )
			{
				new CsArmorType:iArmorType;
				if ( cs_get_user_armor( g_iVictim, iArmorType ) )
				{
					cs_set_user_armor( g_iVictim, 0, CS_ARMOR_NONE );

					SoundHit( id );

					return SKILL_USED;
				}
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillLovelyKiss( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Lovely Kiss", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Puts enemy to sleep." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillMegaKick( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Mega Kick", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 5, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillMegaPunch( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Mega Punch", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillMetronome( SKILL_CALL:iCall, Int:id )
{
	const SKILL_CALL:iCalls = CALL_BIND_DOWN|CALL_BIND_UP|CALL_GIVE_DAMAGE|CALL_TAKE_DAMAGE|CALL_PLAYER_TOUCH|CALL_SPAWN|CALL_DEATH|CALL_EVERY_SECOND|CALL_GIVE_POKEDAMAGE|CALL_TAKE_POKEDAMAGE|CALL_AIM_AT_PLAYER|CALL_SPEED_UPDATE|CALL_ROUND_END|CALL_STATUS_CHANGE|CALL_STATUS_END|CALL_ENTITY_THINK|CALL_ENTITY_TOUCH|CALL_RESET|CALL_CUSTOM;

	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Metronome", .Type = TYPE_NORMAL, .callTypes = CALL_SPAWN|iCalls, .PP = 10, .Charges = 10, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Selects a random ability every round." );
		default:
		{
			//Creating the static within default so it does not create the static variable during register/help
			static POKESKILL:iMetronome[ MAX_PLAYERS + 1 ] = { SKILL_INVALID, ... };

			if ( iCall == CALL_SPAWN || iMetronome[ id ] == SKILL_INVALID )
			{
				new POKESKILL:iSkill, SKILL_CALL:iCallTypes;

				do
				{
					iSkill = POKESKILL:random( _:POKESKILL );
					iCallTypes = SKILL_CALL:SkillInfo( iSkill, SI_CALLTYPE );
				}
				while ( iSkill == SKILL_METRONOME || ( iCallTypes & iCalls ) != iCallTypes );

				DHudEventMessage( id, "Metronome: %s", SkillToName( iSkill ) );
				iMetronome[ id ] = iSkill;

				if ( iCallTypes & iCall )
					return SkillCall( iSkill, iCall, .iPlayer = id, .skillNum = g_iSkillNum, .addDelayTime = false );
			}
			else
			{
				new POKESKILL:iSkill = iMetronome[ id ];
				if ( SKILL_CALL:SkillInfo( iSkill, SI_CALLTYPE ) & iCall )
					return SkillCall( iSkill, iCall, .iPlayer = id, .skillNum = g_iSkillNum, .addDelayTime = false );
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillMimic( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Mimic", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Pokemon mimics enemy's last attack." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillMinimize( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Minimize", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Increases Pokemon's Evade." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillPayDay( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Pay Day", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE|CALL_ROUND_END, .PP = 20, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Get extra money at the end of the round." );
		case CALL_GIVE_DAMAGE:
		{
			gSkillVariable[ id ] += floatround( g_fDamage );
		}
		case CALL_ROUND_END:
		{
			new Int:iBonus = gSkillVariable[ id ];
			if ( iBonus )
			{
				client_print( id, print_center, "PayDay: $%d", iBonus );
				PlayerGiveMoney( id, iBonus );
				gSkillVariable[ id ] = 0;
				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillPound( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Pound", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 35, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Throws nearby players into the air." );
		case CALL_BIND_DOWN:
		{
			new Coord:cOrigin[3], Coord:cPlayerOrigin[3];
			get_user_origin( id, cOrigin );

			new Int:iRadius = StatClamp( id, STAT_SPECIAL, 100, 500 );
			new Float:fUpVelocity = StatClamp( id, STAT_SPECIAL, 100.0, 500.0 );

			new Vector:vVelocity[3];
			new Int:iAffected;
			LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
			{
				if ( id == iPlayer )
					continue;

				get_user_origin( iPlayer, cPlayerOrigin );
				if ( entity_on_ground(iPlayer) && get_distance( cOrigin, cPlayerOrigin ) <= iRadius )
				{
					EntityGetVelocity( iPlayer, vVelocity );
					vVelocity[2] += fUpVelocity;
					EntitySetVelocity( iPlayer, vVelocity );
					iAffected++;
				}
			}

			if ( iAffected )
			{
				SoundEmit( id, SOUND_BIGGUN );

				EffectBlastCircle( .cOrigin = cOrigin,
									.iSprite = SPRITE_SHOCKWAVE,
									.iRadius = iRadius,
									.fLife = 1.0,
									.iWidth = 10,
									.iNoise = 0,
									.iRed = 255,
									.iGreen = 255,
									.iBlue = 255,
									.iAlpha = 255
								);

				return SKILL_USED;
			}
			else
			{
				client_print( id, print_center, "No players close enough" );
				return SKILL_DENY;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillQuickAttack( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Quick Attack", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 30, .Charges = 10, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Get a boost in the direction you are looking." );
		case CALL_BIND_DOWN:
		{
			new Int:iMagnitude = StatClamp( id, STAT_SPECIAL, 400, 700 );

			new Vector:vVelocity[3];
			velocity_by_aim( id, iMagnitude, vVelocity );

			if ( entity_on_ground( id ) )
				vVelocity[2] = floatmax( vVelocity[2], 200.0 );

			EntitySetVelocity( id, vVelocity );

			SoundSpeak( id, SOUND_JUMPLAND );

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillRage( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Rage", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE|CALL_TAKE_DAMAGE, .PP = 20, .Charges = 5, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Increases Attack when damaged." );
		case CALL_GIVE_DAMAGE:
		{
			new Int:iRageDamage = gSkillVariable[ id ];
			if ( iRageDamage )
			{
				SkillDamage( .victim = g_iVictim,
							.attacker = id,
							.damage = iRageDamage
							);
				return SKILL_USED;
			}
		}
		case CALL_TAKE_DAMAGE:
		{
			new Int:iRageDamage = floatround( StatClamp( id, STAT_SPECIAL, g_fDamage * 0.05, g_fDamage * 0.25 ) );
			gSkillVariable[ id ] += iRageDamage;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillRazorWind( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Razor Wind", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Pokemon builds power on the first turn, then attacks on the second turn." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillRecover( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Recover", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Restores HP equal to 1/2 of Pokemon's max HP." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillRoar( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Roar", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Makes wild enemy Pokemon run away." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSandAttack( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Sand Attack", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 15, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Kicks sand at nearby enemies when you attack them." );
		case CALL_GIVE_DAMAGE:
		{
			if ( entity_range( id, g_iVictim ) <= StatClamp( id, STAT_ATTACK, 500.0, 1000.0 ) )
			{
				new Coord:cOrigin[3], Coord:cVelocity[3];
				get_user_origin( id, cOrigin );
				cOrigin[2] -= 48;
				get_user_origin( g_iVictim, cVelocity );
				cVelocity[2] += 48;
				cVelocity[0] -= cOrigin[0];
				cVelocity[1] -= cOrigin[1];
				cVelocity[2] -= cOrigin[2];

				EffectSpray( .cOrigin = cOrigin,
							.cVelocity = cVelocity,
							.iSprite = SPRITE_XPLODE,
							.iCount = StatClamp( id, STAT_ATTACK, 5, 25 ),
							.iSpeed = StatClamp( id, STAT_SPEED, 250, 750 ),
							.iNoise = 50,
							.iRenderMode = kRenderTransAdd
							);

				EffectScreenFlash( .iPlayer = g_iVictim,
									.iRed = 139,
									.iGreen = 59,
									.iBlue = 19,
									.iAlpha = 200,
									.fTime = 1.0,
									.iFadeFlags = ( 1 << 12 )
								);

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillScratch( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Scratch", .Type = TYPE_NORMAL, .callTypes = CALL_GIVE_DAMAGE, .PP = 30, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Extra Damage with Knife." );
		case CALL_GIVE_DAMAGE:
		{
			if ( g_iWeaponID == CSW_KNIFE )
			{
				SkillDamage( .victim = g_iVictim,        //Damage the person that was attacked
							.attacker = id,             //This player is the attacker
							.damage = StatClamp( id, STAT_ATTACK, 5, 65 )
							);
				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillScreech( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Screech", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 40, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Greatly decreases enemy's Defense." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSelfDestruct( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Self Destruct", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 5, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Damages nearby enemies and kills yourself." );
		case CALL_BIND_DOWN:
		{
			new Coord:cOrigin[3];
			get_user_origin( id, cOrigin );

			new Float:fRadius = StatClamp( id, STAT_ATTACK, 300.0, 600.0 );
			new Int:iMaxDamage = StatClamp( id, STAT_ATTACK, 200, 500 );

			SkillAoEDamage( .attacker = id,
							.cOrigin = cOrigin,
							.fRadius = fRadius,
							.iMaxDamage = iMaxDamage,
							.flags = AOE_IGNORE_ATTACKER|AOE_VICTIM_TEAM
						);

			EffectBlastCircle( .cOrigin = cOrigin,
								.iSprite = SPRITE_SHOCKWAVE,
								.iRadius = floatround( fRadius ),
								.fLife = 1.0,
								.iWidth = iMaxDamage / 10,
								.iNoise = 0,
								.iRed = 255,
								.iGreen = 0,
								.iBlue = 0,
								.iAlpha = 255
							);

			SkillDamage( .attacker = id,
							.victim = id,
							.damage = DAMAGE_AUTO_KILL
						);

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSharpen( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Sharpen", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN|CALL_GIVE_DAMAGE, .PP = 30, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Increases knife damage." );
		case CALL_BIND_DOWN:
		{
			if ( gSkillVariable[ id ] )
			{
				client_print( id, print_center, "Knife already sharpened" );
				return SKILL_DENY;
			}

			gSkillVariable[ id ] = 1;
			return SKILL_USED_PAUSE;
		}
		case CALL_GIVE_DAMAGE:
		{
			if ( gSkillVariable[ id ] )
			{
				new Float:fSharpen = StatClamp( id, STAT_ATTACK, 5.0, 65.0 );
				client_print( id, print_center, "Sharpened Knife +%d Damage", floatround( fSharpen ) );
				g_fDamage += fSharpen;
				gSkillVariable[ id ] = 0;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSing( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Sing", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 15, .Charges = 1, .DelayTime = 20.0 );
		case CALL_HELP:     return SkillHelp( "Puts the furthest enemy to Sleep." );
		case CALL_BIND_DOWN:
		{
			new CsTeams:iTeam = cs_get_user_team( id );

			new Coord:cOrigin[3], Coord:cEnemyOrigin[3];
			get_user_origin( id, cOrigin );

			new Int:iRange = StatClamp( id, STAT_SPECIAL, 1000, 2000 );
			new Int:iFurthestEnemy, Int:iFurthestDist, Int:iTempDist;

			LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
			{
				if ( iTeam == cs_get_user_team( iPlayer ) )
					continue;

				get_user_origin( iPlayer, cEnemyOrigin );
				iTempDist = get_distance( cOrigin, cEnemyOrigin );
				if ( iTempDist > iFurthestDist && iTempDist <= iRange )
				{
					iFurthestEnemy = iPlayer;
					iFurthestDist = iTempDist;
				}
			}

			if ( iFurthestEnemy )
			{
				new Int:iSingTime = StatClamp( id, STAT_SPECIAL, 5, 15 );

				StatusApply( iFurthestEnemy,
							.iInflictorID = id, 
							.iStatus = STATUS_ASLEEP,
							.iAmount = iSingTime
							);

				SoundSpeak( iFurthestEnemy, SOUND_SING );
				SoundEmit( id, SOUND_SING );

				return SKILL_USED;
			}
			else
			{
				client_print( id, print_center, "No players close enough" );
				return SKILL_DENY;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSkullBash( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Skull Bash", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 15, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Pokemon lowers head on the first turn, then attacks on the second." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSlam( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Slam", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages the target." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSlash( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Slash", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Has a high critical hit ratio." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSmokescreen( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Smokescreen", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Creates smoke when you are attacked" );
		case CALL_TAKE_DAMAGE:
		{
			new Int:iAttacker = g_iAttacker;
			if ( is_user_alive( iAttacker ) && entity_range( id, iAttacker ) <= StatClamp( id, STAT_SPECIAL, 500.0, 1000.0 ) )
			{
				new Coord:cOrigin[3], Coord:cVelocity[3];
				get_user_origin( id, cOrigin );
				get_user_origin( iAttacker, cVelocity );
				cVelocity[0] -= cOrigin[0];
				cVelocity[1] -= cOrigin[1];
				cVelocity[2] -= cOrigin[2];

				EffectSpray( .cOrigin = cOrigin,
							.cVelocity = cVelocity,
							.iSprite = SPRITE_GAS,
							.iCount = StatClamp( id, STAT_ATTACK, 5, 25 ),
							.iSpeed = StatClamp( id, STAT_SPEED, 250, 750 ),
							.iNoise = 50,
							.iRenderMode = kRenderTransAdd
							);

				EffectScreenFlash( .iPlayer = iAttacker,
									.iRed = 139,
									.iGreen = 139,
									.iBlue = 139,
									.iAlpha = 200,
									.fTime = 1.0,
									.iFadeFlags = ( 1 << 12 )
								);

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSoftboiled( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Softboiled", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Restores 1/2 of the user's max HP. However, this move fails if the user's current HP is 511 or 255 HP below its value at full health." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSonicboom( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Sonicboom", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN|CALL_ENTITY_THINK, .PP = 20, .Charges = 1, .DelayTime = 5.0 );
		case CALL_HELP:     return SkillHelp( "Creates a sonic boom that deals 20 damage." );
		case CALL_BIND_DOWN:
		{
			new Float:fRadius = StatClamp( id, STAT_SPECIAL, 250.0, 500.0 );
			new Int:iEnt = EntitySkillCreate( .iPlayer = id,
										.fThinkTime = 0.1,
										.fDmgTime = 1.0,
										.fKillTime = 6.0,
										.iDamage = 20,
										.fRadius = fRadius,
										.iProperty = SEP_THINK|SEP_AOEDAMAGE|SEP_KILL,
										.iMoveType = MOVETYPE_NONE,
										.iSolidType = SOLID_TRIGGER,
										.iModel = MODEL_NONE,
										.bPlayerOrigin = true,
										.bPlayerAngles = true,
										.vMins = Float:{-1.0,-1.0,-1.0},
										.vMaxs = Float:{1.0,1.0,1.0}
										);

			EntitySetNum( iEnt, ENTITY_AOETYPE, AOE_MAXIMIZE_DAMAGE|AOE_IGNORE_ATTACKER|AOE_VICTIM_TEAM );

			return SKILL_USED_PAUSE;
		}
		case CALL_ENTITY_THINK:
		{
			new Int:iEnt = g_iAttacker;

			new Vector:vOrigin[3], Coord:cOrigin[3];
			EntityGetOrigin( iEnt, vOrigin );
			VectorToCoord( vOrigin, cOrigin );

			if ( get_gametime() >= EntityGetFloat( iEnt, ENTITY_NEXTDAMAGETIME ) )
			{
				EffectBlastCircle( .cOrigin = cOrigin,
									.iSprite = SPRITE_SHOCKWAVE,
									.iRadius = EntityGetNum( iEnt, ENTITY_RADIUS ),
									.fLife = 1.0,
									.iWidth = 10,
									.iNoise = 10,
									.iRed = 255,
									.iGreen = 255,
									.iBlue = 255,
									.iAlpha = 255
								);

				SoundEmit( iEnt, SOUND_BIGGUN );
			}
			else
			{
				EffectImplosion( .cOrigin = cOrigin,
								.iRadius = 50,
								.iCount = 5,
								.fLife = 0.1
							);
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSpikeCannon( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Spike Cannon", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 15, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "" );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSplash( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Splash", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 40, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Doesn't do anything." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillStomp( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Stomp", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Shakes nearby players screens and 30% chance to flinch." );
		case CALL_BIND_DOWN:
		{
			if ( SkillCheck( id, CHECK_IN_AIR, "Stomp" ) )
			{
				return SKILL_DENY;
			}

			new Coord:cOrigin[3], Coord:cPlayerOrigin[3];
			get_user_origin( id, cOrigin );

			new Int:iRadius = StatClamp( id, STAT_SPECIAL, 500, 1000 );
			new Float:fAmplitude = StatClamp( id, STAT_SPECIAL, 5.0, 10.0 );
			new Float:fDuration = StatClamp( id, STAT_SPECIAL, 1.0, 5.0 );
			new Float:fFrequency = StatClamp( id, STAT_SPECIAL, 1.0, 5.0 );

			new CsTeams:iTeam = cs_get_user_team( id );
			LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
			{
				if ( iTeam == cs_get_user_team( iPlayer ) )
					continue;

				get_user_origin( iPlayer, cPlayerOrigin );
				if ( entity_on_ground( iPlayer ) && get_distance( cOrigin, cPlayerOrigin ) <= iRadius )
				{
					EffectScreenShake( .iPlayer = iPlayer,
										.fAmplitude = fAmplitude,
										.fDuration = fDuration,
										.fFrequency = fFrequency
									);

					if ( Chance( 30 ) )
					{
						StatusFlinch( iPlayer );
					}
				}
			}

			SoundEmit( id, SOUND_BIGGUN );

			EffectBlastCircle( .cOrigin = cOrigin,
								.iSprite = SPRITE_SHOCKWAVE,
								.iRadius = iRadius,
								.fLife = 1.0,
								.iWidth = 10,
								.iNoise = 0,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.iAlpha = 255
							);

			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillStrength( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Strength", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 15, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages the target." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillStruggle( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Struggle", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 1, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Used automatically when all of the user's other moves have run out of PP or are otherwise inaccessible. The user receives 1/4 recoil damage. Struggle is classified as a Normal-type move, so it is resisted by Rock-type Pokemon and cannot hit Ghost-type Pokemon at all." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSubstitute( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Substitute", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "The user takes one-fourth of its maximum HP to create a substitute." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSuperFang( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Super Fang", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "This move halves the target's current HP." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSupersonic( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Supersonic", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Confuses the target." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}


PM_FUNC_NORM_ATTRIB SKILL:SkillSwift( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Swift", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN|CALL_ENTITY_THINK, .PP = 20, .Charges = 5, .DelayTime = 15.0 );
		case CALL_HELP:     return SkillHelp( "Ignores Evasion and Accuracy modifiers and will hit Pokemon even if they are in the middle of Fly or Dig. Has a 1-in-256 chance of missing." );
		case CALL_BIND_DOWN:
		{

			SoundHit( id );

			new Int:iEnt = EntitySkillCreate( .iPlayer = id,
											.iProperty = SEP_THINK,
											.fThinkTime = 0.05,
											.fKillTime = StatClamp( id, STAT_SPECIAL, 5.0, 7.5 ),
											.iDamage = StatClamp( id, STAT_ATTACK, 10, 15 ),
											.iMoveType = MOVETYPE_NOCLIP,
											.iSolidType = SOLID_TRIGGER,
											.iModel = MODEL_ROCKET,
											.iSound = SOUND_HIT,
											.iSprite = SPRITE_EEXPLO,
											.bPlayerOrigin = true,
											.bPlayerAngles = true,
											.vMins = Vector:{-5.0,-5.0,-5.0},
											.vMaxs = Vector:{5.0,5.0,5.0},
											.iAimVelocity = 200
										);

			EffectBeamFollow( .iEnt = iEnt,
								.iSprite = SPRITE_TRAIL,
								.fLife = 1.0,
								.iWidth = 1,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.iBrightness = 150
							);

			return SKILL_USED;
		}
		case CALL_ENTITY_THINK:
		{
			new CsTeams:iTeam = cs_get_user_team( id );

			new Int:iEnt = g_iAttacker;
			new Vector:vOrigin[3];
			EntityGetOrigin( iEnt, vOrigin );

			new Float:fPlayerDistance, Vector:vPlayerOrigin[3];

			new Int:iClosestPlayer;
			new Float:fClosestDistance = StatClamp( id, STAT_SPECIAL, 200.0, 500.0 );

			LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
			{
				if ( iTeam == cs_get_user_team( iPlayer ) )
					continue;

				EntityGetOrigin( iPlayer, vPlayerOrigin );
				fPlayerDistance = get_distance_f( vOrigin, vPlayerOrigin );
				if ( fPlayerDistance < fClosestDistance )
				{
					fClosestDistance = fPlayerDistance;
					iClosestPlayer = iPlayer;
				}
			}

			if ( iClosestPlayer )
			{
				if ( fClosestDistance <= 30.0 )
				{
					SkillDamage( .victim = iClosestPlayer,
								.attacker = id,
								.damage = EntityGetNum( iEnt, ENTITY_DAMAGE )
								);

					SoundHit( iClosestPlayer );

					EntityKill( iEnt );
				}
				else
				{
					entity_follow_target( iEnt, iClosestPlayer, StatClamp( id, STAT_SPEED, 300.0, 700.0 ), .bSetAngles = true )
				}

				return SKILL_READY;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillSwordsDance( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Swords Dance", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 30, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Raises the user's Attack by 2 stages." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillTackle( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Tackle", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 35, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Jump forward." );
		case CALL_BIND_DOWN:
		{
			SkillBoost( .iPlayer = id,
						.fVerticalBoost = StatClamp( id, STAT_SPECIAL, 200.0, 400.0 ),
						.fHorizontalBoost = StatClamp( id, STAT_SPECIAL, 400.0, 700.0 ),
						.iBoostDamage = StatClamp( id, STAT_ATTACK, 30, 60 )
						);

			SoundSpeak( id, SOUND_JUMPLAND );

			return SKILL_USED_PAUSE;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillTailWhip( SKILL_CALL:iCall, Int:id )
{
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Tail Whip", .Type = TYPE_NORMAL, .callTypes = CALL_TAKE_DAMAGE, .PP = 30, .Charges = 1, .DelayTime = 0.0 );
		case CALL_HELP:     return SkillHelp( "Chance to push away attackers." );
		case CALL_TAKE_DAMAGE:
		{
			if ( is_user_alive( g_iAttacker ) && StatChance( id, STAT_DEFENSE, 10, 35 ) )
			{
				new Int:iPushStrength = StatClamp( id, STAT_SPECIAL, 250, 450 );
				new Vector:vVelocity[3];

				velocity_by_aim( id, iPushStrength, vVelocity );
				vVelocity[2] = floatmax( vVelocity[2], 200.0 );

				EntitySetVelocity( g_iAttacker, vVelocity );

				new Coord:cOrigin[3];
				get_user_origin( g_iAttacker, cOrigin );

				EffectBeamEntPoint( .iPlayer = 0,
								.iStartEnt = id,
								.cEnd = cOrigin,
								.iSprite = SPRITE_ZBEAM6,
								.iStartFrame = 0,
								.iFrameRate = 10,
								.fLife = 1.0,
								.iLineWidth = iPushStrength / 10,
								.iNoiseAmp = 10,
								.iRed = 255,
								.iGreen = 255,
								.iBlue = 255,
								.iAlpha = 255,
								.iScrollSpeed = 10
							);

				SoundCast( id );

				return SKILL_USED;
			}
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillTakeDown( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Take Down", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "The user receives 1/4 recoil damage." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillThrash( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Thrash", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "The user attacks uncontrollably for 2-3 turns and then gets confused." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillTransform( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Transform", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "The user morphs into a near-exact copy of the target. Stats, stat modifiers, type, moves and appearance are changed; the user's level and HP remain the same and each copied move receives only 5 PP." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillTriAttack( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Tri-Attack", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 10, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages the target." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillViceGrip( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Vice Grip", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 30, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Damages the target." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}

PM_FUNC_NORM_ATTRIB SKILL:SkillWhirlwind( SKILL_CALL:iCall, Int:id )
{
	#pragma unused id
	switch( iCall )
	{
		case CALL_REGISTER: return SkillRegister( .Name = "Whirlwind", .Type = TYPE_NORMAL, .callTypes = CALL_BIND_DOWN, .PP = 20, .Charges = 1, .DelayTime = 1.0 );
		case CALL_HELP:     return SkillHelp( "Escapes from wild battles; fails automatically in trainer and link battles." );
		case CALL_BIND_DOWN:
		{
			return SKILL_USED;
		}
	}
	return SKILL_READY;
}






